#pragma once
#include "DXAMLCommon.h"

#include "CUIElement.h"
#include "FrameworkElementGroupStorage.h"

#include "CDependencyPropertyProxy.h"
class CStyle;
class CType;

class CDataTemplate;
class CControlTemplate;
class CVisualStateGroupCollection;
class CResourceDictionary;
//class TemplateBindingData;

class CFrameworkElement :
	public CUIElement
{

private: 
	void Initialize();
	HRESULT ApplyStyle();
	HRESULT EnsureImplicitStyle(XBOOL isLeavingParentStyle);
	HRESULT EnsureClassName();
	CStyle * GetActiveStyle();
	void SetIgnoreForGetPropertyValueOnAllProxies(CXcpList<CDependencyPropertyProxy> * pStyleProperties, XBOOL bSet);
	void InvalidateStyleProperties(CXcpList<CDependencyPropertyProxy> * pStyleProperties, enum BaseValueSource baseValueSource);

protected: 
	CFrameworkElement();
	CFrameworkElement(CCoreServices * pCore);
	virtual ~CFrameworkElement();
	HRESULT OnStyleChanged(CStyle * pOldStyle, CStyle * pNewStyle, enum BaseValueSource baseValueSource);
public: 
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	virtual HRESULT CreationComplete();
	virtual HRESULT GetMentor(CDependencyObject * * ppMentor);
	virtual CDependencyObject * GetInheritanceParentInternal(XBOOL fLogicalParent);
	virtual HRESULT SetValue(CDependencyProperty * pdp, CValue * pValue);
	virtual HRESULT PullInheritedTextFormatting();
	virtual void EvaluateIsRightToLeft();
	virtual HRESULT NotifyPropertyChanged(CDependencyProperty * pdp, CValue * pValue);
	virtual CDependencyObject * GetLogicalParent();
	HRESULT EnsureLayoutProperties(XBOOL fDefaultOK);
	static HRESULT EnsureGroupStorage(CDependencyObject * pObject, CDependencyProperty * pDp, XBOOL forGetValue);
	static HRESULT InvalidateImplicitStyles(CUIElement * pElement, CResourceDictionary * pOldResources);

	static HRESULT ActualWidth(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	static HRESULT ActualHeight(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	static HRESULT Parent(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	virtual XFLOAT GetActualOffsetX();
	virtual XFLOAT GetActualOffsetY();
	virtual XFLOAT GetSpecifiedWidth();
	virtual XFLOAT GetSpecifiedHeight();
	virtual HRESULT GetActualWidth(XFLOAT * peWidth);
	virtual XFLOAT GetActualWidth();
	virtual HRESULT GetActualHeight(XFLOAT * peHeight);
	virtual XFLOAT GetActualHeight();
	virtual HRESULT SetTemplatedParent(CDependencyObject * pDO);
	virtual HRESULT SetTemplateBinding(struct XamlPropertyToken tokTargetProperty, struct XamlPropertyToken tokSourceProperty);
	virtual CDependencyObject * GetTemplatedParent();
	virtual HRESULT DisconnectFromTemplatedParent();
	virtual CDependencyObject * GetNamescopeParent();
	virtual struct IPALUri * GetBaseUri();
	void ClearTemplateBindingData();
	virtual HRESULT OnApplyTemplate();
	HRESULT InvokeApplyTemplate(XBOOL * bAddedVisuals);
	HRESULT InvokeFocus(enum FocusState focusState, XUINT32 * returnValue);
	HRESULT MeasureOverrideForPInvoke(struct XSIZEF availableSize, struct XSIZEF * pDesiredSize);
	HRESULT ArrangeOverrideForPInvoke(struct XSIZEF finalSize, struct XSIZEF * pNewFinalSize);
	virtual XINT32 IsPropertySetByStyle(CDependencyProperty * pdp);
	virtual HRESULT SetIsSetByStyle(CDependencyProperty * pdp, XBOOL fSet);
	virtual XINT32 DoesStyleHaveBinding(CDependencyProperty * pdp);
	virtual HRESULT SetStyleHasBinding(CDependencyProperty * pdp, XBOOL fSet);
	virtual HRESULT UpdateImplicitStyle(CStyle * pOldStyle, CStyle * pNewStyle, XBOOL bForceUpdate, XBOOL bUpdateChildren, XBOOL isLeavingParentStyle);
	XUINT8 IsPropertyTemplateBound(CDependencyProperty * pdp);
	XINT32 IsDefaultHeight();
	XINT32 IsDefaultWidth();
	HRESULT AddLogicalChild(CDependencyObject * pNewLogicalChild, XBOOL bContentTemplateboundOnManagedSide);
	HRESULT RemoveLogicalChild(CDependencyObject * pOldLogicalChild);
	HRESULT GetImplicitDataTemplate(CType * pType, CDataTemplate * * ppTemplate);
	static HRESULT DataContext(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	virtual HRESULT GetValueFromStyle(XUINT32 uPropertyId, XBOOL bIsCoreProperty, CValue * pValue, XBOOL * pbGotValue);
	static HRESULT FlowDirection(struct Xcp_IDependencyObject *, XUINT32, CValue *, CValue *);
	virtual HRESULT SetCursor(enum MouseCursor cursor);
protected: 
	virtual HRESULT GetTemplate(CControlTemplate * * ppTemplate);
	virtual HRESULT ApplyTemplate(XBOOL & fAddedVisuals);
	virtual HRESULT MeasureOverride(struct XSIZEF availableSize, struct XSIZEF & desiredSize);
	virtual HRESULT ArrangeOverride(struct XSIZEF finalSize, struct XSIZEF & newFinalSize);
	virtual XUINT32 CompareForCircularReference(CFrameworkElement * pTreeChild);
	virtual void SetIsUpdatingBindings(XBOOL fIsUpdatingBinding);
	virtual HRESULT MeasureCore(struct XSIZEF availableSize, struct XSIZEF & desiredSize);
	virtual HRESULT ArrangeCore(struct XRECTF_WH finalRect);
	virtual HRESULT UpdateLayoutClip(XBOOL forceClipToRenderSize);
	virtual HRESULT EnterImpl(CDependencyObject * pNamescopeOwner, struct EnterParams params);
	virtual HRESULT LeaveImpl(CDependencyObject * pNamescopeOwner, struct LeaveParams params);
private: 
	void GetMinMax(XFLOAT & minWidth, XFLOAT & maxWidth, XFLOAT & minHeight, XFLOAT & maxHeight);
	void ComputeAlignmentOffset(struct XSIZEF & clientSize, struct XSIZEF & inkSize, XFLOAT & offsetX, XFLOAT & offsetY);
	XFLOAT ComputeWidthInMinMaxRange(XFLOAT width);
	XFLOAT ComputeHeightInMinMaxRange(XFLOAT height);
	HRESULT ValidateStyleTargetType(CType * pTargetType);
	HRESULT GetGridPropertyValue(XUINT32 uIndex, XUINT32 * puValue);
	HRESULT InvalidateProperty(CDependencyPropertyProxy * pDependencyPropertyProxyProxy, enum BaseValueSource baseValueSource);
	XINT32 IsPropertyBitSet(CDependencyProperty * pdp, union CDependencyObject::BitField & field);
	HRESULT SetIsPropertyBitSet(CDependencyProperty * pdp, union CDependencyObject::BitField & field, XBOOL fSet);
public:
	enum ImplicitStyleProvider
	{
		ImplicitStyleProvider_None = 0,
		ImplicitStyleProvider_Self= 1,
		ImplicitStyleProvider_Parent = 2,
		ImplicitStyleProvider_AppWhileNotInTree = 3,
		ImplicitStyleProvider_AppWhileInTree = 4
	};

private: 
	enum ImplicitStyleProvider m_eImplicitStyleProvider;

public: 
	XFLOAT m_eWidth;
	XFLOAT m_eHeight;
	enum MouseCursor m_eMouseCursor;
	CResourceDictionary * m_pResources;
	struct FrameworkElementGroupStorage * m_pLayoutProperties;
	CDependencyObject * m_pLogicalParent;
	CStyle * m_pStyle;
	CVisualStateGroupCollection * m_pVisualStateGroups;
	union CDependencyObject::BitField m_setByStyle;  
	union CDependencyObject::BitField m_styleHasBinding;  

private: 
	static const struct FrameworkElementGroupStorage DefaultLayoutProperties;  


	struct TemplateBindingData * m_pTemplateBindingData;
	CStyle * m_pImplicitStyle;
	CXString * m_pClassName;
	CWeakRef * m_pImplicitStyleParentWeakRef;



};
